/**
 * 超跌反弹 CDFT 众赢投顾 主图指标
 */

import {movingAverage as _average} from './MA'
import * as zytgTools from './ZYTG_UTIL'

const CDFT_DOWN_DAYS = 30    //下跌天数范围
const CDFT_DOWN_SIZE = 0.3   //下跌比例范围
const CDFT_SECTION_MIN_DAYS = 4       //平台最小天数
const CDFT_SECTION_MAX_DAYS = 10      //平台最大天数
const CDFT_SECTION_MIN_COUNT = 2      //回调反弹最少平台数
const CDFT_MAX_FANTAN_SIZE = 1.1      //回调反弹最大比例 


let initParam = {
  name: 'CDFT',
  type: 'polyline',
  caculateParam: [60],  // 默认用
}

/**
 * Caculator 数据处理
 *
 */
/**
 * Caculator 数据处理
 * @param  {array} rawData
 * @param  {array} caculateParam
 * @param  {string} prop //指定计算哪个字段   close 
 * @return {array} 一维数组
 *
 * 使用说明（render.k.chart.js）：
      let qstzData = caclInitData([60], store.data)
      let qstzResult = QSTZCalc.caculate(qstzData) 
 *
 * 数据结构说明
[
  {
    "startIndex": 86,
    "endIndex": 90,
    "startTime": "2017-07-11",
    "endTime": "2017-07-18",
    "sections": [
    {
        "startIndex": 86,
        "endIndex": 90,
        "startTime": "2017-07-11",
        "endTime": "2017-07-16",
        "length": 4
    }],
    "icons": [
      {icon: "up_arrow", time: "2017-02-13", color: "red", x: 82, y: 0.656}
    ],
    "eye":
    {
        "index": 88,
        "time": "2017-07-13",
        "price": 104.68,
        "moveRight": true
    }
  }
]
 */
function caculate (rawData, caculateParam, dataSliceCount) {
  if (!(rawData instanceof Array)) throw new Error('Data or caculateParam is not Array')
  let period = (caculateParam instanceof Array) ? caculateParam[0] : initParam.caculateParam
  let mathData = _caculator(rawData, period, dataSliceCount)
  return mathData
}

function _caculator (rawData, period, dataSliceCount) {
  let minLow30Days = zytgTools.calcMaxMinOfDays(rawData, 'low', 30, zytgTools.MMD_GET_MIN)
  let dataPoints = []

  let startI = dataSliceCount > CDFT_DOWN_DAYS ? dataSliceCount - CDFT_DOWN_DAYS : 0
  for (let i = startI; i < rawData.length; i++) {
    let minPrice = 0
    let maxPrice = 0
    let minPriceIndex = 0
    let maxPriceIndex = 0
    let mayHasPoint = false
    let currentSections = []
    for (let j = i - CDFT_DOWN_DAYS; j < i; j++) {
      //不足30天数据，不计算
      if (j <= 0) break
      // console.log("j checking", rawData[i].time, rawData[j].time)
      //前面存在一个高点H1，并且距离计算K线在30天之内，至最低点L1跌幅大于30%
      maxPriceIndex = rawData[j].high > maxPrice ? j : maxPriceIndex
      maxPrice = rawData[maxPriceIndex].high
      mayHasPoint = (maxPrice * (1 - CDFT_DOWN_SIZE) > minLow30Days[i])
      //在H1到L1的下跌过程中，没有出现反弹10%以上的走势
      mayHasPoint = mayHasPoint && (!minPrice || (rawData[j].high < minPrice * CDFT_MAX_FANTAN_SIZE))
      minPriceIndex = (rawData[j].low < minPrice || minPrice == 0) ? j : minPriceIndex
      minPrice = rawData[minPriceIndex].low

      //如果和上一个30D区间重叠则忽略本区间
      if (mayHasPoint && dataPoints.length) {
        let oldPoint = dataPoints[dataPoints.length - 1]
        if (oldPoint.startIndex <= maxPriceIndex && maxPriceIndex <= oldPoint.endIndex) {
          mayHasPoint = false
        }
      }
      if (!mayHasPoint) {
        continue
      }

      //查找section平台
      let sectionCount = 0
      let isSection = true
      let sectionStartLow = rawData[j].low
      let sectionMaxHigh = rawData[j].high
      let sectionMinLow = sectionStartLow
      for (let k = 1; k <= CDFT_SECTION_MAX_DAYS + 1; k++) {
        // console.log("k checking", rawData[i].time, rawData[j].time, rawData[j+k].time)

        //存在一个低点L2在之后的至少三个交易日没有收盘低于L2，平台持续时间为4-10日;完成信号为收盘跌破平台的最低点L3。最多检查到CDFT_SECTION_MAX_DAYS + 1天
        if (!rawData[j + k] || (sectionStartLow > rawData[j + k].close && k < CDFT_SECTION_MIN_DAYS)|| (sectionMinLow > rawData[j + k].close && k >= CDFT_SECTION_MIN_DAYS))
          isSection = false
        if (k < CDFT_SECTION_MIN_DAYS && !isSection) {
          break
        }
        //超长平台不算小平台，要记录起来忽略掉
        let isBig = false
        if (k > CDFT_SECTION_MAX_DAYS && isSection ) {
          isSection = false
          isBig = true
        }
        sectionMinLow = isSection && (rawData[j + k].low < sectionMinLow) ? rawData[j + k].low : sectionMinLow

        //达到最低连续k线要求
        if ((k >= CDFT_SECTION_MIN_DAYS) && (!isSection)) {
          let section = {
            startIndex: j,
            endIndex: j + k - 1,
            startTime: rawData[j].time,
            endTime: rawData[j + k - 1].time,
            length: k - 1,
            low: sectionMinLow,
            high: sectionMaxHigh,
            isBig: isBig
          }
          //若起跌高点H1的K线处于一个平台中或与接下来的平台有重合部分，即H1的K线低点要小于平台的高点，那么这个平台无效
          let valid = maxPriceIndex < section.startIndex
          valid = valid && (section.high < rawData[maxPriceIndex].low)
          if (valid) {
            if (currentSections.length) {
              let lastSection = currentSections[currentSections.length - 1]
              //检查是否和上一个平台重叠，且平台不挨着，即一个平台的完成K线后面接着出现另一个平台或完成K线是另一个平台的开始，若挨着，计为一个平台，并以持续时间较长的平台有效
              if (section.high >= lastSection.low || section.startIndex <= lastSection.endIndex + 2) {
                if (section.length >= lastSection.length) {
                  currentSections.splice(currentSections.length - 1, 1, section)
                }
              } else {
                currentSections.push(section)
              }
            } else {
              currentSections.push(section)
            }
            // console.log("section found", rawData[i].time, rawData[j].time, section, currentSections)
          }
          break
        }
        sectionMaxHigh = isSection ? Math.max(sectionMaxHigh, rawData[j + k].high) : sectionMaxHigh
      }
    }
    //平台处于高点与低点之间，在下跌过程中的平台数>=2
    let validCount = 0
    for (let k = 0; k < currentSections.length; k++) {
      if (currentSections[k].endIndex < i && !currentSections[k].isBig) {
        validCount++
      }
    }
    mayHasPoint = mayHasPoint && (validCount >= 2)
    if (mayHasPoint) {
      let point = {
        startIndex: maxPriceIndex,
        endIndex: minPriceIndex,
        startTime: rawData[maxPriceIndex].time,
        endTime: rawData[minPriceIndex].time,
        sections: currentSections,
        icons: []
      }
      let lastSection = currentSections[currentSections.length - 1]
      //结束信号：H1以来的最低点反弹超过10%结束标红
      let index = lastSection.endIndex + 1
      while (rawData[index] && (rawData[index].high <= minLow30Days[index - 1] * CDFT_MAX_FANTAN_SIZE)) {
        //确保最大跌幅>30%
        if (maxPrice * (1 - CDFT_DOWN_SIZE) > minLow30Days[index - 1]) {
          point.icons.push({
            icon: "up_arrow", color: "blue", time: rawData[index].time, x: index - dataSliceCount, y: rawData[index].low
          })
        }
        index++
      }

      // let eye
      // if (point.icons.length > 0) {
      //   eye = {}
      //   let count = point.icons[point.icons.length-1].x - point.icons[0].x
      //   let moveRight = (count % 2 > 0)
      //   let center = (count == 0) ? point.icons[0].x : point.icons[0].x + Math.floor(count / 2)
      //   eye.x = center
      //   eye.time = rawData[dataSliceCount + center]['time']
      //   eye.price = minLow30Days[dataSliceCount + point.icons[point.icons.length-1].x + 10]
      //   eye.moveRight = moveRight
      // }
      // point.eye = eye
      dataPoints.push(point)
    }
  }
  // console.log(JSON.stringify(dataPoints))
  return dataPoints
}


export default {
  initParam: initParam,
  caculate: caculate
}
